package com.design.reactor.stretchIO._1_singleReactorSingleThread;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class Handler  implements Request {
	 final SocketChannel socketChannel;
	    final SelectionKey selectionKey;

	    static final int MAX_IN = 1024;
	    static final int MAX_OUT = 1024;
	    ByteBuffer input = ByteBuffer.allocate(MAX_IN);
	    ByteBuffer output = ByteBuffer.allocate(MAX_OUT);
	    static final int READING = 0, SENDING = 1;
	    int state = READING;

	    public Handler(Selector sel, SocketChannel c) throws IOException {
			System.out.println("-------------- Handler 构造方法 -------------");
	        socketChannel = c;
	        c.configureBlocking(false);
	        // 也可以注解注册SelectionKey.OP_READ; 这里先不关心任何事件， 后面注册读事件
	        selectionKey = socketChannel.register(sel, 0);//注册一个不存在的事件
	        selectionKey.attach(this);
	        selectionKey.interestOps(SelectionKey.OP_READ);//注册读事件
	        sel.wakeup();//唤醒前一个阻塞的socket
	    }

	    @Override
	    public void reqHandler() {
	    	boolean isWritable= selectionKey.isWritable();
			boolean isReadable= selectionKey.isReadable();
			boolean isAcceptable= selectionKey.isAcceptable();
			System.out.println(" -------state: "+state+" ; 可写 ："+isWritable+" ; 可读 ："+isReadable);
	        try {
	            if (state == READING) {
	                read();
	            } else if (state == SENDING) {
	                write();
	            }
	        } catch (IOException ignored) {
	            // ignored.
	        }
	    }

	    void read() throws IOException {
			output.clear();
	        socketChannel.read(input);
			input.flip();
			String msg = String.valueOf(StandardCharsets.UTF_8.decode(input).array());
			System.out.println("---- read() :" + msg);
	        process();
	        state = SENDING;
	        selectionKey.interestOps(SelectionKey.OP_WRITE);
	    }

	    void write() throws IOException {
			output.clear();
	        String msg="to client write content";
			output.put( msg.getBytes() );
			output.flip();
			socketChannel.write(output);
	        if (outputIsComplete()) {
	            selectionKey.cancel();
	        }
	    }

	    boolean inputIsComplete() {
	        // 加入实现
	        return true;
	    }

	    boolean outputIsComplete() {
	        // 加入实现
	        return true;
	    }

	    void process() {
	        // 加入实现
	    }
}
